Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

16_Код и шаблон страницы (Дмитрий Котеров)
Goto page 1, 2  Next
Author Message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Jun 03, 2004 3:24 pm ()
   Post subject: 16_Код и шаблон страницы
Reply with quote

dklab.ru/chicken/nablas/16.html
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 388
   поощрить/наказать


PostPosted: Thu Jun 03, 2004 3:38 pm (спустя 13 минут)
   Post subject:
Reply with quote

Перечитал 16-ую наблу 5-6 раз. Многое до сих пор осталось непонятным.
Итак:
  1. Почему так важно сделать первичным представление? Это же адски тяжело - переучиться. Да и зачем?
  2. По поводу примения идеологии "компонентности". Имхо, Вы (ДК) всё сильно перекосили на один бок, хотя ситуация симметрична. Если код ведущий, то компоненты - это шаблоны и подшаблоны. Если ведёт представление, то компоненты - это код, и для низ спарведливы все те же 4-ре свойства, которые Вы выдумали на ходу.
Мне кажется, что первичен алгоритм. Представьте себя ребёнком, которому диктуют: "...да, он сегодня слишком плох", он дописывет, а потом ему говорят - это была прямая речь, и бедный малыш вынужден все исправлять - втискивать кавычки и т.д. Я вот к чему: если я только в конце страницы узнаю, что-то, от чего зависит начало страницы, то как это поправить - контент-то написан...
Back to top
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Thu Jun 03, 2004 7:12 pm (спустя 3 часа 33 минуты)
   Post subject:
Reply with quote

Дмитрий Котеров:
Хм... Через год прочтение Вашей статьи еще раз заставляет задуматься... :). Я наконец-то до конца понял Вашу идею... :).
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Jun 03, 2004 8:06 pm (спустя 54 минуты)
   Post subject:
Reply with quote

Переучиваться с чего?

Давайте немного поговорим о том, какие бывают сайты. Рассмотрим две крайности.

Первая крайность — это полностью динамический сайт. Например, форум. У него всего 4 разных шаблона (соответственно, главная страница, список форумов, список топиков, тексты сообщений), но зато очень и очень много логики (контроллеров штук 20-30).

Вторая крайность — наоборот, сайт с минимумом динамики. Например, какой-нибудь сайт, где практически все страницы делаются по одному шаблону, но содержат различный текст. На таком сайте в явном виде представлена структура разделов, да и вообще они выглядят очень естественно (как правило, одна страница — один файл).

Шаблонизатор, конечно, применяется в основном для сайтов второго типа. Его характерные особенности приведены в статье — это, например, наследование информации от родительских разделов, а также возможность наследования и легкой смены шаблона дизайна. В принципе, для форума его тоже можно применять, но тут он не дает значительной выгоды (с точки зрения наследования).

Теперь про компонентность. Компонента по определению — это не только заменяемая, но также и легко встраиваемая часть системы. Иными словами, различные (причем существенно различные по своему назначению) компоненты можно легко добавлять и удалять. Ясно, что в такой роли шаблон выступать не может — шаблон всегда привязан к коду (контроллеру), который готовит для него даные, да и несколько шаблонов для одного и того же контроллера всегда выглядят очень похоже. Компонента — это именно контроллер, именно код.

Невозможно добавить шаблон, если для него нет контроллера (это будет рыба, а не шаблон). В то же время, вполне реально написать контроллер, вообще никак не привязывая к нему шаблон (к примеру, можно просто распечатывать на странице все данные, пришедшие из контроллера, — в Смарти есть для этого специальные средства).

Я думаю, мы по-разному понимаем слово «первичный». Я понимаю его как нечто, что запускает остальные подсистемы. Вы же — как то, без чего работать нельзя. Конечно, и без кода, и без шаблона ничего не сделать. Тем не менее, в компонентном подходе первичен именно шаблон. Представьте себе дизайнера, который мышкой перетаскивает в FrontPage компонент-новости, настраивает его дизайн, и вот — на страниыах появляются новости. При этом что перетаскивается? Вызов контроллера, и перетаскивается он в то место, где нужно отобразить данные.
Back to top
View user's profile Send private message Send e-mail
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 4:49 pm (спустя 2 месяца 28 дней 20 часов 42 минуты)
   Post subject: Связь контроллера и блока в компонентном подходе
Reply with quote

Мой вопрос связан со связями между компонентами и "блоками".
Я попытаюсь использовать терминологию, используемую самим автором наблы.
Вот выдержка:
Quote:
Controller (Контроллер):
Код бизнес-логики, занимающийся приемом данных от пользователя, а также выступающий посредником между Моделью и Шаблоном. Например, в сценарии гостевой книги Модель может хранить все записи, оставленные пользователями (сколько бы их ни было), а Шаблон -отображать по 10 сообщений на страницу. В этом случае выборкой очередных 10 сообщений из базы данных Модели, а также формированием списка URL следующих и предыдущих страниц книги занимается Контроллер.

Компонентный подход
Развитие системы MVC, в котором ведущая роль принадлежит Шаблону, а не Контроллеру. Контроллеры в компонентном подходе называют Компонентами. Шаблон (обязательно активный) самостоятельно определяет, какие Компоненты нужны для его обработки, и подключает соответствующий программный код. Элементы компонентного подхода: Шаблон, Модель, Компоненты.

Блок:
Cоставная часть Шаблона компонентного подхода. Задает оформление некоторого фиксированного участка страницы (например, Блок новостей, Блок авторизации, Блок названия, Блок "хлебных крошек" и т.д.). Обычно каждому Блоку соответствует не более одного Компонента (но может не соответствовать и ни одного; в таком случае говорят о статическом Блоке). Не следует думать, что Блок содержит только оформление страницы, но не ее контент. Это не обязательно. Если страницы сайта в основном статические, то их текст может содержаться непосредственно в соответствующих Блоках (например, в Блоке Текст).
В приведенных наблой 16 примерах все действительно близко к идеалу, поскольку компоненты weather и news практически друг от друга не зависят. Соответственно связь "компонента - блок" прослеживается довольно четко.

Как быть в ситуации, когда связи намного теснее? Приведу пример из жизни.

Есть страница с информацией о работнике некой фирмы. На странице есть следующие блоки:

Блок 1: Карточка самого человека: адрес, телефон...
Блок 2: Карточка фирмы, где работает этот человек

Порядок следования блоков может быть, естественно, произвольным.
Как примерно выглядят в нашем случае контроллеры (компоненты) для этих блоков:
Code (php): скопировать код в буфер обмена
<?php
 //
 $contact_id = $GET['contact_id']; //
 $Contact = new ContactPerson($contact_id);
 $contact_detail = $Contact->getDetail();
 
 //
?>

<?php
 //
 $contact_id = $GET['contact_id'];
 $Contact = new ContactPerson($contact_id);
 $contact_detail = $Contact->getDetail();
 
 $business_id = $contact_detail['businees_id'];
 $Business = new Business($business_id);
 $business_detail = $Business->getDetail();

 //
?>
Преимущества: все признаки и преимущества компонентного подхода, озвученные в набле 16: независимость, повторное использование, ...

Недостатки: Объект Contact вынужден создаваться дважды, а метод $Contact->getDetail(), в котором непосредственно находится SQL запрос, также дважды выполняться.
В приведенном примере это может и не являться проблемой, ибо пример прост. В реальности, если разговор идет о 10-15 подобных блоках на странице, то умножение числа запросов к базе начинает играть существенную роль.

Альтернативный вариант (Общий контроллер)
Code (php): скопировать код в буфер обмена
<?php
 // общий контроллер (в данном примитивном случае - это копия контроллера 2)
 $contact_id = $GET['contact_id'];
 $Contact = new ContactPerson($contact_id);
 $contact_detail = $Contact->getDetail();

 $business_id = $contact_detail['businees_id'];
 $Business = new Business($business_id);
 $business_detail = $Business->getDetail();
 
 //далее $business_detail и $contact_detail разбираются блоками 1 и 2
?>
Преимущества: оптимизировали количество запросов до необходимого минимума
Недостатки: исчезла независимость компонент и возможность повтороного использования контроллера на других страницах(вариант при котором блок 1 использует общий контролер с лишним опросом объекта Business не рассматривается, т.к. он перечеркивает преимущества проведенной оптимизации)


Вопрос: Это суровая правда жизни, или где-то допущен серьезный просчет в проектировании?

Варианты:

1) Неправильно спроектированы классы
2) Неправильно произведена разбивка на блоки
3) ... ?

Буду очень рад узнать ваше мнение.


С уважением, Владимир Шапиро
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 5:10 pm (спустя 21 минуту)
   Post subject:
Reply with quote

Владимир Шапиро wrote:
Объект Contact вынужден создаваться дважды
Это потому, что Вы делаете в коде Компонента то, чем должна заниматься Модель (ядро). Никто ведь не мешает организовывать Компоненты модульно, выделяя повторяющийся код в библиотеки ядра (и заодно при этом заботясь о единичности нужных объектов).

В Вашем примере следует использовать не new ContactPerson($contact_id), а что-то вроде Kernel::getPerson($contact_id). А уж ядро будет решать, создавать ему новый экземпляр или возвращать уже созданный ранее (аналог кэширования персон по $contact_id).
Back to top
View user's profile Send private message Send e-mail
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 5:18 pm (спустя 7 минут)
   Post subject:
Reply with quote

Если я правильно понял, вы предлагаете использовать механизм Factory (если я правильно помню, так подобное называется в Java).
Code (php): скопировать код в буфер обмена
// Здесь ContactFactory и BusinessFactory классы ядра (модели)
ContactFactory :: getPerson($contact_id);
BusinessFactory :: getBusiness($business_id);
Или вы предлагаете использовать единую фабрику классов под названием Kernel для инстанцирования всего что угодно в проекте?
(Здесь у меня есть опасения, что на больших проектах код такого Kernel будет очень сложно сопровождать ввиду его объемности).
Back to top
View user's profile Send private message
Евгений Галашин
Модератор



Joined: 29 Dec 2003
Posts: 1861
Карма: 32
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 5:29 pm (спустя 11 минут)
   Post subject:
Reply with quote

Владимир Шапиро wrote:
(Здесь у меня есть опасения, что на больших проектах код такого Kernel будет очень сложно сопровождать ввиду его объемности).
Не факт. зависит от того, что берёт на себя фабрика, а что собственно класс.
Back to top
View user's profile Send private message
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 5:58 pm (спустя 28 минут)
   Post subject:
Reply with quote

Евгений Галашин wrote:
Не факт. зависит от того, что берёт на себя фабрика, а что собственно класс.
Исходя из практики проекта, в котором мне приходится участвовать:

1) Пусть есть некая сущность. Тот же Contact или, если рассматривать предложенный Дмитрием подход, ContactFactory.
2) У ContactFactory определяется так называемая функция поиска ContactFactory :: search(). Эта функция очень общая. На вход она получает массив с условиями поиска и желаемым списком полей, которые мы хотим получить в результате. Причем поля могут быть не только из таблиц БД, напрямую соответствующих сущности, но и из таблиц смежных сущностей, связи с которыми определны внутри класса (например поля Business).
3) Методы типа getPerson() или getDetail() являются по сути оболочками (wrapper), вызвающих функцию search с рядом предопределнных параметров.

Сделано это может быть для того, чтобы избежать ситуации "одна функция - один запрос", когда мы имеем N SQL запросов, отличающихся друг от друга условиями в секции WHERE.

Очевидно, что код таких поисковиков, с определением возможных связей может растягиваться на несколько сотен строчек.
теперь предположим, что подобных сущностей у нас в проекте около 10. В этом случае меня сильно смущает размер такого Kernel.
Back to top
View user's profile Send private message
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 6:13 pm (спустя 14 минут)
   Post subject:
Reply with quote

Дмитрий Котеров:



Дополнительная вопрос: куда выносится логика, общая для всей страницы? Под таковой я понимаю:

1) проверка прав на страницу
2) проверка корректности переданных параметров
3) ...

Это ведь также должно находится в ведении некоего контроллера? Получается, что здесь мы должны говорить не о контроллере конкретного блока, а о некотором общем контроллере всей страницы?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 7:19 pm (спустя 1 час 6 минут)
   Post subject:
Reply with quote

Владимир Шапиро wrote:
Если я правильно понял, вы предлагаете использовать механизм Factory
Нечто вроде того. Только Factories (Фабрики) все же обычно бывают не статическими (как в примере выше), а виртуальными. Т.е. метод getPerson() вызывается не для класса, а доя объекта-фабрики (т.е. он не статический, а виртуальный). Фабрики еще поэтому называют "виртуальными конструкторами" (ибо можно подсунуть другой объект-фабрику, у которого метод getPerson() будет существенно отличаться).
Владимир Шапиро wrote:
куда выносится логика, общая для всей страницы?
Все зависит от того, что это за логика. Например, для проверки прав на всю страницу логично сделать отдельный Компонент, а проверку корректности параметров для некоторого Компонента должен реализовывать этот же Компонент (кому, как не ему, лучше известно, что считать некорректным). Общие куски кода можно выделять в Модель (ядро).

Разделение на Компоненты, прежде всего, предназначено для повторного использования кода в других проектах. Например, понадобилась где-то еще функциональность, которая есть в некотором проекте, - берем соответствующий Компонент и копируем.

Кстати, Вам, наверное, стоит посмотреть топик про новый "книжный" шаблонизатор в форуме книги. Там все это реализовано, и даже есть примеры.
Back to top
View user's profile Send private message Send e-mail
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 7:56 pm (спустя 36 минут)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Кстати, Вам, наверное, стоит посмотреть топик про новый "книжный" шаблонизатор в форуме книги. Там все это реализовано, и даже есть примеры.
Спасибо за совет :) Пример обязательно посмотрю, а вот сам топик больше посвящен проблемам установки шаблонизатора, нежели принципам его функционирования.

Поэтому, с вашего разрешения, я задам еще один свой вопрос, который у меня был по шаблонизатору здесь.
Back to top
View user's profile Send private message
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 7:59 pm (спустя 3 минуты)
   Post subject: Сложность условий в шаблонизаторе
Reply with quote

Допустим у нас есть контроллер, поставляющий список новостей с определенными аттрибутами.
Задача: оформить новости по разному в зависимости от условий, заданных этим атрибутами

Сложность условий может варьироваться. Например:
1) Все новости позднее заданной даты подсветить серым.
2) Поставить возле новостей из тематики такой-то галочку.
3) В зависимости оттого, кто является автором (источником) новости, вынести определенную функциональность в виде пиктограмм.

Данные задачи содержат, на мой взгляд, две состовляющие:
1) логическую (проверка заданных условий)
2) оформительскую (оформление в зависимости от этих условий)

Предположим, что используемый нами шаблонизатор содержит необходимые конструкции ветвления, циклов и набор простейших операций сравнения.

Если код проверки условий не сложный (как в 1), то дизайнеру или верстальщику не составит труда проверить все это самостоятельно в шаблоне.
В случае (2), а тем более (3) проверка может быть сколь угодно сложной, вплоть до неободимости инкапсуляции логики проверки в отдельную функцию.

Вопрос: как поступать в случаях 2 и 3. Очевидно, что возлагать ответственность за проверки такой сложности на плечи дизайнера - сомнительное решение.

Вариантом является повторная переработка данных самим контролером и устанвка понятных дизайнеру переменных-флагов, с которыми можно работать с помощью обычных конструкций ветвления в шаблонах.
Этот вариант не нравится мне тем, что заставляет автора контроллера думать над всевозможными вариантами оформления его данных ("какие флаги мне вычислять?"). Что по идее головная боль дизайнера.

Что вы думаете по этому поводу?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Sep 01, 2004 8:48 pm (спустя 49 минут)
   Post subject:
Reply with quote

В общем случае ответа на такой вопрос дать нельзя. Надо смотреть по обстоятельствам. В любом случае, в шаблоне не должно быть сложных участков кода, а в Компоненте - элементов оформления. Причем, мне думается, наличие оформления в Компоненте - хуже, чем наличие сложной логики в Шаблоне.

Вариант с флагами, вероятно, предпочтительнее (именно через него сделаны в книжном шаблонизаторе Компонент Templier::Menu).
Back to top
View user's profile Send private message Send e-mail
Владимир Шапиро
Заглянувший



Joined: 31 Aug 2004
Posts: 9
Карма: 1
   поощрить/наказать


PostPosted: Thu Sep 02, 2004 7:25 pm (спустя 22 часа 37 минут)
   Post subject: почему Smarty?
Reply with quote

Дмитрий Котеров:

Большое спасибо за ответы. Приятно осозновать, что в большинстве пунктов наши рассуждения совпадают.
Тем не менее, мой поток вопросов еще не иссяк :)

Я хотел бы подробнее остановиться на самом шаблонизаторе. Почему из всех php-шаблонизаторов был выбран и пропатчен (!) Smarty - для меня очевидно. Мой вопрос несколько иной: почему был выбран php-based шаблонизатор вместо XML/XSLT?

Некую слабую попытку сравнения я нашел здесь:
www.devpapers.com/article/18
Тем не менее не все аргументы автора "против" Smarty и "за" XSLT я нахожу убедительными.

До сегодняшнего дня я использовал в качестве механизма шаблонов XSLT и вот что я думаю о его преимуществах и недостатках:

XSLT. Преимущества.
1. Очень мощный гибкий механизм трансформаций, разделения по шаблонам (собственно, для чего и создавался)
2. При хорошем парсере быстро, возможно быстрее Smarty
3. W3C стандарт
4. (не уверен) В случае статичных страниц или сайтов сводит роль php к минимуму, тем самым повышая переносимость сайта или модуля на любую друг технологическую платформу, с поддержкой xslt (Java, Perl .Net....)

XSLT. Недостатки.
1. Дизайнер все-таки может повесится. Синтаксис xslt более громоздкий ем в Smarty
2. Обычный кодер тоже может повесится. XSLT - не процедурный язык и требует на старте определенных умственных усилий от новичка.
3. В стандартной поставке PHP4 + Sablotron - тормозит
4. Разнородность проекта, фатальная для маленькой команды. Когда проект сопровождается одним-двумя программистами, то приходится нпостоянно переключатся между XSLT и PHP, решая задачи в разных идеологиях.
5. (не уверен) Однажды заставив думать себя на xslt, очень трудно соскользнуть назад. Все время кажется что это шаг в каменный век, но это видимо сугубо субъективно.

Интересно услышать ваше мнение по выбору Smarty vs. XSLT. Ограничен ли такой выбор сферой решаемых задач или Smarty объективно лучше?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Sep 02, 2004 7:56 pm (спустя 31 минуту)
   Post subject:
Reply with quote

Владимир Шапиро wrote:
Почему из всех php-шаблонизаторов был выбран и пропатчен (!) Smarty - для меня очевидно.
Smarty - это наиболее стандартный и динамически развивающийся язык шаблонов из тех, что существуют для PHP. Конечно, не без недостатков (например, в стандартном Smarty очень неудобно отлаживать шаблоны - номера строк в E_NOTICE показываются в откомпилированном шаблоне и не совпадают с номерами в исходном файле).

Что касается XSLT, то тут все просто: чтобы по-настоящему использовать компонентный подход вместе с XSLT, нужна XML-база данных (на самом деле, даже не XML-БД, а графовая БД, где возможна множественность родителей, циклические ссылки и т.д.), умеющая выполнять XSLT "внутри себя" и поддерживающая прозрачную подгрузку узлов по требованию (изотропность данных). Такой СУБД, к сожалению, пока еще никто не написал.

Если осилите, почитайте вот это:
xpoint.ru/archive/threads/65/13179.html
xpoint.ru/forums/internet/XML/thread/15146.xhtml (вот это в особенности)
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Sep 02, 2004 8:01 pm (спустя 4 минуты)
   Post subject:
Reply with quote

Да, забыл сказать. Сложность XSLT, в общем-то, поверхностная. Никто не мешает прикрутить к нему WYSIWYG-редактор (об этой идее я как-то писал в форуме), и в итоге дизайнеру вообще не придется иметь дело с элементами программирования. Например, xsl:if можно обозначить как блок кода с плюсиком (сворот/разворот), xsl:foreach - как блок, могущий размножаться произвольное число раз. Со Smarty в этом отношении сложнее, потому что там много неформальных и нестандартизированных вещей (в этом отношении XSLT просто параноидально упрощен и унифицирован, вплоть до имен атрибутов у разных тэгов; видно, что люди изрядно поломали голову). Поэтому для WYSIWYG (а я верю, что за WYSIWYG все же бущушее активных страниц) Smarty подходит хуже, чем XSLT.
Back to top
View user's profile Send private message Send e-mail
Григорий Курышев
Участник форума



Joined: 24 Sep 2004
Posts: 29
Карма: 2
   поощрить/наказать

Location: Екатеринбург

PostPosted: Wed Sep 29, 2004 2:03 pm (спустя 26 дней 18 часов 2 минуты; написано за 14 секунд)
   Post subject:
Reply with quote

По части проблемы с разным расположением "шаблона страницы" и "нового рисунка дизайнера".
Дмитрий, почему бы не использовать в шаблоне страницы стандартный тег <base href="http..."></base> и хранить всю графику в заданной директории (директориях), например, в корне сайта? А в шаблоне страницы для графики задавать относительные пути уже от <base href=... .
Для шаблонизатора, который приведен в вашей книге - это самое, на мой взгляд, простое решение, в частности в вопросе наследования одного и того же шаблона в поддиректории.
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Sep 29, 2004 6:16 pm (спустя 4 часа 13 минут; написано за 31 секунду)
   Post subject:
Reply with quote

Об этом, кажется, сказано в статье (а может, в новой книге, точно не помню). Смысл тот, что путаница с путями весьма непонятна для дизайнера.
Back to top
View user's profile Send private message Send e-mail
Юрий Насретдинов
Модератор



Joined: 13 Mar 2003
Posts: 8642
Карма: 198
   поощрить/наказать

Location: 007 495

PostPosted: Wed Sep 29, 2004 9:10 pm (спустя 2 часа 53 минуты; написано за 13 секунд)
   Post subject:
Reply with quote

Григ де Гриз:
Дмитрий Котеров:
Чайник wrote:
Использование абсолютных путей типа /img/image.gif не предлагать — пример утопичен по своей простоте. Кроме того, не всегда хочется захламлять директорию картинок изображениями, которые не будут использоваться нигде, кроме как в определенном разделе сайта.
Back to top
View user's profile Send private message Send e-mail
Григорий Курышев
Участник форума



Joined: 24 Sep 2004
Posts: 29
Карма: 2
   поощрить/наказать

Location: Екатеринбург

PostPosted: Thu Sep 30, 2004 10:25 am (спустя 13 часов 14 минут; написано за 34 секунды)
   Post subject:
Reply with quote

Видимо в новой книге... Однако, идею понял. Был не прав. :)
Back to top
View user's profile Send private message Send e-mail
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Mon Aug 22, 2005 6:48 pm (спустя 10 месяцев 22 дня 8 часов 23 минуты)
   Post subject:
Reply with quote

Прочитал статью о шаблонизаторе и задумался о представленном синтаксисе:
Quote:
<!-- Блок новостей -->
<h2>Последние новости:</h2>
<DATASRC src="News">
<FOREACH src=News>
    <li>$i-я новость: $news
</FOREACH>
<hr>
Согласен представить дизайнера не программистом, тогда зачем ему знать циклы ?

Идея состоит в следующем:
1. Контроллер знает сколько, каких и в каком логическом состоянии имеется данных
2. Контроллер должен вывести данные в соответствующем оформлении.
3. Оформление знает шаблон.
4. Контроллер должен иметь возможность выбрать из нескольких шаблонов тот, который
   подходит для текущей (обрабатываемой) записи

Получается идеология а-ля XML/XSLT

Код :
<!-- Блок новостей -->
<CONTROLLER src="News">
  <PATTERN>
    <h2>Последние новости:</h2>
    <UL>
    $NEWSLIST
    </UL>
  </PATTERN>

  <ITEM is_selected="NO">
    <LI><A HREF="$ITEM_HREF">$ITEM_TEXT</A></LI>
  </ITEM>

  <ITEM is_selected="YES">
    <LI><A HREF="$ITEM_HREF"><b>$ITEM_TEXT</b></A></LI>
  </ITEM>
</CONTROLLER>
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Mon Aug 22, 2005 7:10 pm (спустя 21 минуту; написано за 22 секунды)
   Post subject:
Reply with quote

IlVin, Вы рассказываете сейчас модель с ведущим контроллером - со всеми вытекающими.
Back to top
View user's profile Send private message Send e-mail
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Tue Aug 23, 2005 12:51 pm (спустя 17 часов 41 минуту; написано за 12 минут 45 секунд)
   Post subject:
Reply with quote

Это скорее гибрид.
Шаблон говорит шаблонизатору:
 - какой контроллер выбрать,
 - какие данные выбрать контроллеру из БД
 - как контроллеру оформить кусок HTML текста, в котором выводятся данные из БД
Эти пункты подразумевают то, что дизайнер имеет представление о контроллере и интерфейсе взаимодействия с контроллером из шаблона, а также о структуре этих данных.
Например, листинг новостей: там есть титл новости, краткое описание, ссылка. Есть состояния: новость кликнута не кликнута. И т.д. и т.п.
На мой взгляд кажется логичным на этом этапе передать контроллеру управление созданием HTML текста листинга новостей, но по шаблонам, доступным в шаблоне.
Я написал:
Quote:
2. Контроллер должен вывести данные в соответствующем оформлении.
Имеются в виду данные, которые касаются только листинга новостей (как пример). О структуре всего шаблона страницы контроллер не имеет ни малейшего представления!
Инициирование вызова контроллера и определение начальных параметров, например: базового URL, относительно которого контроллер сгенерирует HTML текст листинга новостей, осуществляется исключительно из шаблона.
Quote:
Вы рассказываете сейчас модель с ведущим контроллером - со всеми вытекающими.
Вот вытекающие из моей модели "плохие" мне пока не очевидны :-( готов открыть глаза :-)
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Tue Aug 23, 2005 6:12 pm (спустя 5 часов 20 минут; написано за 1 минуту 49 секунд)
   Post subject:
Reply with quote

Один и тот же контроллер может использоваться для нескольких разных шаблонов. При этом в каком-то из шаблонов могут выводиться не все данные, сгенерированные контроллером. Например, если контроллер выдает новости, а также подробную информацию об авторе каждой новости (в едином массиве, к примеру), то один шаблон может выводить эту подробную информацию, а другой - нет (и все это в разных оформлениях к тому же). К примеру, один шаблон - краткие тексты новостей на главной странице, другой шаблон - архив новостей.
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Tue Aug 23, 2005 6:12 pm (спустя 26 секунд; написано за 24 секунды)
   Post subject:
Reply with quote

Так что контроллер не знает, какой шаблон используется на момент его вызова, и не может им "рулить".
Back to top
View user's profile Send private message Send e-mail
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Tue Aug 23, 2005 7:21 pm (спустя 1 час 8 минут; написано за 6 минут 44 секунды)
   Post subject:
Reply with quote

Правильно. Контроллер - это черный ящик с параметрами, которыми и управляет шаблон. Скажет шаблон как выводить автора - контроллер так и выведет (контроллер должен иметь интерфейс ко всем данным, которые вытягиваются из БД), а если шаблону нужны супер извраты, то на это есть callback функции...
Добавлю, что в одном шаблоне можно задать форму вывода имени автора, а в другом задать пустоту и автор соответственно выведен не будет...
Я просто глобализовал Ваш пример и предложил циклы перенести в контроллер, таким образом усложнив его, а оформление отдельных элементов и параметры цикла оставить в шаблоне, отказавшись таким образом от непонятного дизайнеру тега <FOREACH>
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Aug 24, 2005 5:37 pm (спустя 22 часа 15 минут; написано за 19 секунд)
   Post subject:
Reply with quote

ОК. Опишите, как Вы предлагаете реализовать пример из forum.dklab.ru/viewtopic.php?p=91716#91716
Back to top
View user's profile Send private message Send e-mail
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Wed Aug 24, 2005 5:54 pm (спустя 17 минут; написано за 55 секунд)
   Post subject:
Reply with quote

Quote:
Сложность условий может варьироваться. Например:
1) Все новости позднее заданной даты подсветить серым.
2) Поставить возле новостей из тематики такой-то галочку.
3) В зависимости оттого, кто является автором (источником) новости, вынести определенную функциональность в виде пиктограмм.
Этот? (Данная Вами ссылка ссылается на наш диалог.)
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Thu Aug 25, 2005 12:36 pm (спустя 18 часов 41 минуту; написано за 1 секунду)
   Post subject:
Reply with quote

IlVin
Дмитрий Котеров wrote:
При этом в каком-то из шаблонов могут выводиться не все данные, сгенерированные контроллером. Например, если контроллер выдает новости, а также подробную информацию об авторе каждой новости (в едином массиве, к примеру), то один шаблон может выводить эту подробную информацию, а другой - нет (и все это в разных оформлениях к тому же). К примеру, один шаблон - краткие тексты новостей на главной странице, другой шаблон - архив новостей.
Back to top
View user's profile Send private message Send e-mail
Mich
Участник форума
Warnings: 1


Joined: 15 Jun 2005
Posts: 197
Карма: -3
   поощрить/наказать


PostPosted: Thu Aug 25, 2005 8:31 pm (спустя 7 часов 54 минуты; написано за 6 минут 43 секунды)
   Post subject:
Reply with quote

Наверное, так:
IlVin wrote:
4. Контроллер должен иметь возможность выбрать из нескольких шаблонов тот, который
   подходит для текущей (обрабатываемой) записи
+ думаю вы (Дмитрий Котеров) неправы. Это та же схема 16-ой наблы, но усложненная со своими плюсами и минусами. Вот по-вашему:
Code (any language): скопировать код в буфер обмена
контроллер {
    цикл {
        оформление (шаблон или как?)
    }
}
Вот то, что предлагает IlVin:
Code (any language): скопировать код в буфер обмена
В примере IlVin только дополнительная нагрузка на контроллер, т.к. он должен еще и правильно выбирать оформление (шаблон или как?), проводить итерацию и записывать в переменную. Но научить этому можно. +: дизайнеру легче; -: дизайнер должен догадывать о связи "результат работы цикла" -> "оформление (шаблон или как?)".

IlVin, а реализация уже есть? Пользуетесь?
Back to top
View user's profile Send private message Send e-mail
Maus
Модератор



Joined: 29 Jun 2003
Posts: 8151
Карма: 271
   поощрить/наказать

Location: пос. Омсукчан Магаданской области

PostPosted: Fri Aug 26, 2005 11:07 am (спустя 14 часов 36 минут; написано за 1 минуту 23 секунды)
   Post subject:
Reply with quote

Mich wrote:
Code (any language): скопировать код в буфер обмена
контроллер {
    результат работы цикла
}
оформление (шаблон или как?)
Я извиняюсь, но как-то не понимаю, как может выводиться результат работы цикла, если контроллер не содержит оформления....
Back to top
View user's profile Send private message
Mich
Участник форума
Warnings: 1


Joined: 15 Jun 2005
Posts: 197
Карма: -3
   поощрить/наказать


PostPosted: Fri Aug 26, 2005 7:03 pm (спустя 7 часов 55 минут; написано за 4 минуты 11 секунд)
   Post subject:
Reply with quote

Maus wrote:
Я извиняюсь, но как-то не понимаю, как может выводиться результат работы цикла, если контроллер не содержит оформления....
Контроллер выбирает оформление из темплейта, я же написал:
Mich wrote:
т.к. он должен еще и правильно выбирать оформление (шаблон или как?), проводить итерацию и записывать в переменную.
понимаете? Контроллер запускается в темплейте, получает содержимое контроллер {}, далее видит, что здесь нужен цикл, ищет в содержимом контроллер {} оформление для цикла, проводит все итерации, используя полученное оформление, записывает результат итераций в переменную - продолжается работа темплейта.

Ед. сложность: боюсь, что научив всему этому шаблонизатор, мы получим тот же недружелюбный для дизайнера XML/XSLT. Хотя попробовать стоит.
Back to top
View user's profile Send private message Send e-mail
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Fri Aug 26, 2005 10:59 pm (спустя 3 часа 55 минут; написано за 26 минут 28 секунд)
   Post subject:
Reply with quote

Mich, большое спасибо за поддержку :-)
Реализации того, что здесь написано нет (как раз занимаюсь этим), но есть прототип, похожий по принципу действия на то, что здесь написано.
Прототип.
Пришел я работать в контору, в которой сайты велись на всеми любимом фронтпейдже. Все страницы содержали и текст и оформление. Все загибались с ссылками и нечаянными модификациями оформления. Так как народ очень шустро набивал тексты во фронтпейдже, было решено оставить его в качестве ворда. Всем было сказано, что на сайте размещаются не страницы, а документы. Документы содержат логически отформатированный текст и больше ничего. И есть служебные файлы, в которых можно с помощью фронтпейджа расставить ссылки на документы.
Эти служебные файлы являются БД для меню - там содержатся гиперссылки и текст/картинка меню.
В закрытой части у меня динамический шаблон (набла 8), но реализованная мною самостоятельно (после реализации нашел куроводство).
Так вот, нужно из служебных файлов информацию оформлять в виде меню со ссылками. Данные меню понятны: текст ссылки, гиперссылка. И есть состояния: активная ссылка или неактивная. Написал функцию, которая в динамическом шаблоне вызывается так:
<%
use RTL::MENU;

my $lMenu = RTL::MENU::make(
DOCUMENT_ROOT => $ENV{'DOCUMENT_ROOT'},
PATH_INFO => $ENV{'PATH_INFO'},
menuFileName => '-leftMenu.htm',
'SplitItems' => sub { # CallBack функция по разбору пунктов меню, находящихся в файле -leftMenu.htm
  my @out; # В принципе в RTL::MENU::make зашиты CallBack функции по умолчанию, но эта для "финтов"
                      # Правильнее перенести ее в пакет RTL::MENU, а здесь задать переменной номер парсера исходного файла.
  while( $_[0] =~ /<[lL][iI][^>]*>.*?<[aA][^>]+[hH][rR][eE][fF][^=>"]*=[^">]*"([^">]*)"[^>]*>(.*?)<\/[aA]>.*?<\/[lL][iI]>/gso ){
    my %item;
    $item{'HREF'} = $1;
    $item{'TITLE'}= $2;
    push @out, \%item;
  };
  return @out;
},
# Шаблон пункта меню активного, т.е. того, который содержит ссылку на запрошенный документ
'ItemTplA' => [q|<tr><td width="1%" valign="top"><img src="/_design_/b.gif"></td><td width="99%"><H6><b><a href="%%HREF%%" class="leftMenuItem">%%TITLE%%</a></b></H6></td></tr>|],
# Обращаю внимание, что это ссылка на массив. Можно задать несколько шаблонов подрад, которые будут последовательно применяться
# для следующего пункта меню.

# Шаблон пункта меню не активного
'ItemTplNA' => [q|<tr><td width="1%" valign="top"><img src="/_design_/b.gif"></td><td width="99%"><H6><a href="%%HREF%%" class="leftMenuItem">%%TITLE%%</a></H6></td></tr>|],

# Шаблон меню активного
'MenuTplA' => [q|<table cellspacing="0" cellpadding="0" border="1" borderCOLOR="#091871" style="border-collapse: collapse; border: 1px solid #091871; border-bottom-width: 1px;" width="160">
    <tr><td bgCOLOR="#091871" align="center" style="border-collapse: collapse; border: 1px solid #091871;"><font color="white"><h5><b>%%MTITLE%%</b></h5></font></td></tr>
    <tr><td><table cellspacing="0" cellpadding="1" border="0" width="100%">
    %%ITEMS%%
    </table></td></tr>
    </table>|],
# Шаблон разделителя пунктов меню
'itemDivider'=>"\n",
# Шаблон разделителя менюшек
'menuDivider'=>"<br>\n\n",
);
%>

Как видим - Вызов функции - это вызов контроллера, которому передаются шаблоны для формирования текста меню.
Вызов этой функции и передачу шаблонов можно формализовать и заключить в теги, что я проделал выше в топике.
Данный пример взят с работающего сайта ilvin.msk.ru/. Сайт управляется только фронтпейджем.
А еще есть сайт компании, в которой я работаю teleserv.ru/ Тоже управляется фронтпейджем, рулимым несколькими
девчушками, которые вечно путают ссылки :-)
Back to top
View user's profile Send private message
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Fri Aug 26, 2005 11:04 pm (спустя 5 минут; написано за 7 минут 23 секунды)
   Post subject:
Reply with quote

XML/XSLT вместе мы не получим. Получим в шаблоне - XSLT, а в контроллере - XML.
Т.е. если контроллер будет внутри себя генерировать XML из базы, брать из шаблона XSLT схему, применять ее к сгенерированному XML и все это возвращать обратно.
Дизайнер загнется под XSLT, а программер напьется от XML :-)
И уже непонятно то ли дезигнера учить XSLT, то ли объясниять как работает <FOREACH>.
Думаю, дезигнер с большим оптимизмом будет учить XSLT, так как это все-таки стандарт :-)
Интересно - где надыбать самый шустрый XSLT процессор? В PHP как обстоят дела с XML/XSLT ?
Back to top
View user's profile Send private message
Mich
Участник форума
Warnings: 1


Joined: 15 Jun 2005
Posts: 197
Карма: -3
   поощрить/наказать


PostPosted: Sat Aug 27, 2005 9:35 am (спустя 10 часов 30 минут; написано за 3 минуты 15 секунд)
   Post subject:
Reply with quote

IlVin wrote:
В PHP как обстоят дела с XML/XSLT ?
В PHP 5 неплохо. Там большой выбор, но что-то конкретное посоветовать не могу.

Я вообще-то представлял себе это совсем по-другому. Что-то типа плагина под Smarty (жаль что у вас все на Perl), XSLT вообще не трогать. Может попробую сделать.
IlVin wrote:
Думаю, дезигнер с большим оптимизмом будет учить XSLT, так как это все-таки стандарт
С меньшим пессимизмом :) Не будет дизайнер учить XSLT, на то он и Дизайнер...
Back to top
View user's profile Send private message Send e-mail
Алексей Блинов
Guest





Карма: 388
   поощрить/наказать


PostPosted: Tue Nov 15, 2005 6:07 pm (спустя 2 месяца 19 дней 8 часов 32 минуты; написано за 11 минут 21 секунду)
   Post subject: вопрос про шаблонизаторы...
Reply with quote

После прочтения наблы, стало интересно... Если я правильно понял, то Smarty как раз не совсем то, что надо... так так, насколько я понял после прочтения доков на сайте смарти, ведущим является все-таки код... в нем нужно заполнить переменные и вызвать смарти (да, можно сразу вызвать смарти и сделать много-много своих ф-ий, их и звать... но это не проще :)).
В тоже время, недавно я пробовал разворачивать блог с использованием WordPress (wordpress.org/) - и насколько мне стало понятно из кода шаблонов там - это как раз то, о чем говориться в набле (ну почти... там все-таки не делают свой язык для дизайнера... там что-то типа <?php getNews() ?>).
В чем вопрос? Передомной стоит сейчас задача сделать вэб-доступ к ПО, которой есть... И я перед выбором:
1. PHP-in-HTML(HTML-in-PHP)
2. Smarty
3. Templier
4. a-la WordPress
n. может что-то еще...

первый вариант - самый простой на первый взгляд... но вот дизайнер из меня никакой :))
второй - тоже вроде хорош
третий - тоже вроде хорош, вот только посмотреть что это я пока не смог... у меня нет денвера, да и ставить его некуда (MacOS). Книги я пока не купил, а на форуме из из просто просмотра архива ничего путного не видно...
четвертый - пока наиболее симпатичен

Ну в общем после большого вступления: может кто-нибуть осветить для меня концы тунелей? :) и помочь сделать выбор?
Back to top
ПролезНеожиданноВнутрь
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Apr 20, 2006 2:30 pm (спустя 5 месяцев 4 дня 20 часов 23 минуты; написано за 32 секунды)
   Post subject:
Reply with quote

Алексей Блинов
В МacOS есть Apache, зачем Вам Денвер???
Back to top
Дмитрий Чечеткин
Участник форума



Joined: 15 Sep 2005
Posts: 49
Карма: 2
   поощрить/наказать

Location: UGEE-UKOO-URKK-ULLI

PostPosted: Mon May 15, 2006 9:05 pm (спустя 25 дней 6 часов 35 минут; написано за 16 минут 11 секунд)
   Post subject:
Reply with quote

Модель с ведущим контроллером (применена в CMS Phoenix):

Существует три типа элемента страницы:
Шаблон на XML
    Содержит код html, оформленный по правилам xml, с тегами, вызывающими снипплеты и переменными вида #VAR varname#
Снипплеты на обычном php
    Самые обычные скрипты, используемые для вывода каких-либо данных.
Библиотеки на ООП php
    Классы, предоставляющие функции для работы с пользователями, БД и прочими источниками информации.

При этом все страницы сайта хранятся в бд и имеют параметр - обрабатывающий шаблон и шаблон-контейнер.
После получения запроса система исполняет шаблон-контейнер, который в себе содержит вызов снипплета called.
called соответственно вставляет вместо себя скомпилированный шаблон-обработчик, который форматирует запрошенные данные.

плюсы:
    получается язык, наподобие XSLT, но более привычный для программиста и дизайнера.
    Работа дизайнера сводится к созданию примерного шаблона с рыбой, которую программист в последствии заменит на код шаблонизатора (кстати, у вас неправильные предпосылки - превращать дизайн в шаблон имхо, должен программист вместе с дизайнером)
    Сама страница теперь может быть помещена в любом месте сайта, и потом - также просто перенесена путем простого изменения параметра записи в БД об этой странице.

минусы:
    неисправимых минусов не заметил ;)
Back to top
View user's profile Send private message
IlVin
Заглянувший



Joined: 18 Aug 2005
Posts: 14
Карма: 0
   поощрить/наказать

Location: Москва

PostPosted: Tue May 16, 2006 9:25 am (спустя 12 часов 19 минут; написано за 8 минут 17 секунд)
   Post subject:
Reply with quote

Mich wrote:
... XSLT вообще не трогать.
Вы оказались правы: переварить XSLT для меня оказалось довольно сложным.
Его я все-таки переварил, но он какой-то чужеродный для меня... (особый
геморрой с HTML текстом, передаваемым в XSLT в контейнере CDATA) Пошел по
пути провайдеров... В контроллер ввожу несколько параметров, определяющих
какой провайдер поставляет данные, а какой их преобразовывает в HTML.
Получилось, что можно просто считать файл и отправить его либо на
Perl-Script, либо на XSLT обработчик в зависимости от того, что из себя
представляет файл...
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Goto page 1, 2  Next
Page 1 of 2    Email to a Friend.
Post a reply
Username
Subject
Господа спамеры и оптимизаторы!

Вы можете даже и не пытаться вставлять в текст поста ссылки - они все равно автоматически удаляются (вернее, тэги <a> заменяются на тэги <u>).

Но если не поверите и все же попытаетесь - как только увидите, что все безрезультатно, удалите свой пост, пожалуйста. Модераторы тоже люди, нехорошо, если они погрязнут в тоннах спама.
     

Disable BBCode in this post
Disable Smilies in this post
    HTML is OFF
BBCode is ON
Smilies are ON
You cannot post new topics in this forum. You can reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML